package restapi

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"
)

const (
	promServerUrl     = "http://192.168.0.125:9090"
	promQueryApi      = "/api/v1/query"
	promQueryRangeApi = "/api/v1/query_range"
	NodeExporterPort  = ":9100"
)

// InstantVectorsResponse query查询的返回值
type InstantVectorsResponse struct {
	Status string              `json:"status"`
	Data   *InstantVectorsData `json:"data"`
}

// InstantVectorsData query查询的返回值的数据部分
type InstantVectorsData struct {
	ResultType string            `json:"resultType"`
	Result     []*InstantVectors `json:"result"`
}

type InstantVectors struct {
	Metric *ResultMetric `json:"metric"`
	Value  []interface{} `json:"value"`
}

type ResultMetric struct {
	Instance string `json:"instance"`
}

func getCPUUtilization(instances string) (*InstantVectorsResponse, error) {

	query := createUrl(promServerUrl, promQueryApi, "?query=",
		"(1-sum(irate(node_cpu_seconds_total{mode='idle',instance=~'", instances, "'}[5m]))by(instance))*100")

	client := http.Client{}
	u, err := url.Parse(query)
	resp, err := client.Get(u.String())
	defer resp.Body.Close()

	if err != nil {
		return nil, err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	instantVector := &InstantVectorsResponse{}
	err = json.Unmarshal(body, instantVector)

	if err != nil {
		return nil, err
	}

	return instantVector, nil
}

func getHardDiskUsage(instances string) (*InstantVectorsResponse, error) {

	query := createUrl(promServerUrl, promQueryApi, "?query=",
		"(1-sum(node_filesystem_free_bytes{instance=~\"",
		instances,
		"\"})by(instance)/sum(node_filesystem_size_bytes{instance=~\"",
		instances,
		"\"})by(instance))*100")

	client := http.Client{}
	u, err := url.Parse(query)
	resp, err := client.Get(u.String())
	defer resp.Body.Close()

	if err != nil {
		return nil, err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	instantVector := &InstantVectorsResponse{}
	err = json.Unmarshal(body, instantVector)

	if err != nil {
		return nil, err
	}

	return instantVector, nil
}

func getRAMUtilization(instances string) (*InstantVectorsResponse, error) {

	query := createUrl(promServerUrl, promQueryApi, "?query=",
		"(1-node_memory_MemFree_bytes{instance=~\"",
		instances,
		"\"}/node_memory_MemTotal_bytes{instance=~\"",
		instances,
		"\"})*100")

	client := http.Client{}
	u, err := url.Parse(query)
	resp, err := client.Get(u.String())
	defer resp.Body.Close()

	if err != nil {
		return nil, err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	instantVector := &InstantVectorsResponse{}
	err = json.Unmarshal(body, instantVector)

	if err != nil {
		return nil, err
	}

	return instantVector, nil
}

func createUrl(params ...string) string {

	if len(params) == 0 {
		return ""
	}

	var buf bytes.Buffer

	for _, param := range params {
		buf.WriteString(param)
	}

	return buf.String()
}
